#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

#include "file_queue.h"
#include "cicd_config.h"
#include "cicd_common.h"

#define FILE_DELETE "delete.txt"

typedef struct _node {
    char token[35];
    char owner[20];
    char repo[30];
    char file[256];
    char sha[45];
    time_t timestamp;
    struct _node *next;
}node;

// 带头结点，采用头出队，尾入队
typedef struct {
    node *data;
    node *rear;
}file_queue;

file_queue file_queue_head;
static char g_file_name[256] = { 0 };

void queue_file_init() {
    FILE *fp = NULL;
    char token[35];
    char owner[20];
    char repo[30];
    char file[256];
    char sha[45];
    time_t timestamp;

    snprintf(g_file_name, sizeof(g_file_name), "/home/%s/.cicd/%s", getlogin(), FILE_DELETE);
    fp = fopen(g_file_name, "r");

    file_queue_head.data = (node *)malloc(sizeof(node));
    strcpy(file_queue_head.data->file, "test");
    file_queue_head.data->next = NULL;
    file_queue_head.rear = file_queue_head.data;
    if(NULL == fp) {
        printf_info("No file queue\n");
        return;
    }
    while(!feof(fp)) {
        node *temp = (node *)malloc(sizeof(node));
        memset(token, 0, sizeof(token));
        memset(owner, 0, sizeof(owner));
        memset(repo, 0, sizeof(repo));
        memset(file, 0, sizeof(file));
        memset(sha, 0, sizeof(sha));
        timestamp = 0;
        fscanf(fp, "%s %s %s %s %s %ld\n", token, owner, repo, file, sha, &timestamp);
        if(strlen(token) == 0) {
            break;
        }
        strncpy(temp->token, token, sizeof(temp->token));
        strncpy(temp->owner, owner, sizeof(temp->owner));
        strncpy(temp->repo, repo, sizeof(temp->repo));
        strncpy(temp->file, file, sizeof(temp->file));
        strncpy(temp->sha, sha, sizeof(temp->sha));
        temp->timestamp = timestamp;

        temp->next = NULL;

        file_queue_head.rear->next = temp;
        file_queue_head.rear = temp;
    }
    fclose(fp);
}

int queue_file_add(const char *access_token, const char *owner, const char *repo, const char *file_path, const char *sha) {
    node *temp = (node *)malloc(sizeof(node));
    FILE *fp = NULL;

    if(access_token == NULL || owner == NULL || repo == NULL || file_path == NULL || sha == NULL) {
        if(temp != NULL) {
            free(temp);
        }
        return QUEUE_ERR_BAD_INPUT;
    }

    strncpy(temp->token, access_token, sizeof(temp->token));
    strncpy(temp->owner, owner, sizeof(temp->owner));
    strncpy(temp->repo, repo, sizeof(temp->repo));
    strncpy(temp->file, file_path, sizeof(temp->file));
    strncpy(temp->sha, sha, sizeof(temp->sha));
    temp->timestamp = time(NULL);

    temp->next = NULL;

    file_queue_head.rear->next = temp;
    file_queue_head.rear = temp;

    fp = fopen(g_file_name, "a+");
    if(NULL == fp) {
        printf_warning("Can not open ~/.cicd/delete.txt\n");
    }
    else {
        printf_info("Add delete queue ok\n");
        fprintf(fp, "%s %s %s %s %s %ld\n", access_token, owner, repo, file_path, sha, temp->timestamp);
        fclose(fp);
    }

    return QUEUE_OK;
}

int queue_file_get(char *access_token, char *owner, char *repo, char *file_path, char *sha) {
    node * temp = file_queue_head.data->next;
    time_t current_time;
    FILE *fp = NULL;
    current_time = time(NULL);

    if(access_token == NULL || owner == NULL || repo == NULL || file_path == NULL || sha == NULL) {
        return QUEUE_ERR_BAD_INPUT;
    }

    if(temp == NULL) {
        return QUEUE_STATUS_EMPTY;
    }

    if(current_time - temp->timestamp < 7 * 24 * 3600) {
        return QUEUE_NOT_TIME_OUT;
    }

    if(temp == file_queue_head.rear) {
        file_queue_head.rear = file_queue_head.data;
    }
    file_queue_head.data->next = temp->next;

    strncpy(access_token, temp->token, sizeof(temp->token));
    strncpy(owner, temp->owner, sizeof(temp->owner));
    strncpy(repo, temp->repo, sizeof(temp->repo));
    strncpy(file_path, temp->file, sizeof(temp->file));
    strncpy(sha, temp->sha, sizeof(temp->sha));

    free(temp);

    temp = file_queue_head.data->next;
    fp = fopen(g_file_name, "w");
    if(NULL == fp) {
        printf_warning("Can not update ~/.cicd/delete.txt\n");
        return QUEUE_OK;
    }
    while(NULL != temp) {
        fprintf(fp, "%s %s %s %s %s %ld\n", temp->token, temp->owner, temp->repo, temp->file, temp->sha, temp->timestamp);
        temp = temp->next;
    }
    fclose(fp);

    return QUEUE_OK;
}

void debug_queue_file() {
    node *temp = file_queue_head.data->next;
    if(temp == NULL) {
        printf("no file uploaded\n");
        return;
    }
    while(temp != NULL) {
        printf("token:%s\nowner:%s\nrepo:%s\nfile:%s\nsha:%s\ntimestamp:%ld\n", temp->token, temp->owner, temp->repo, temp->file, temp->sha, temp->timestamp);
        temp = temp->next;
    }
}

void debug_queue_file_free() {
    node *temp = file_queue_head.data;
    node *tempfree = NULL;
    while(temp != NULL) {
        tempfree = temp;
        temp = temp->next;
        free(tempfree);
    }
}